package com.wlyuan.open.domain.source.dispatcher.conversion;

import com.wlyuan.basic.api.IRelationService;
import com.wlyuan.core.exception.AssertUtils;
import com.wlyuan.core.exception.ValueError;
import com.wlyuan.open.constants.CarrierTypeEnum;
import com.wlyuan.open.constants.CustomerTypeEnum;
import com.wlyuan.open.dto.OpenTemplateSyncDTO;
import com.wlyuan.open.dto.quotation.QuotationDetailDTO;
import com.wlyuan.open.remote.facade.Address;
import com.wlyuan.open.remote.facade.AddressDTO;
import com.wlyuan.open.utils.LongUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Optional;

/**
 * @author lijing
 * @description
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class OpenDispatcherTemplateConversion implements OpenDispatcherConversion<OpenTemplateSyncDTO> {
    private final BaseOpenDispatcherConversion baseOpenDispatcherConversion;
    @DubboReference(check = false)
    private final IRelationService relationService;

    @Override
    public void convert(OpenTemplateSyncDTO source) {
        //租户
        convertTenant(source);
        //用户
        convertUser(source);
        //上游
        convertUp(source);
        //下游
        convertDown(source);
        //地区
        convertArea(source);
    }

    private void convertTenant(OpenTemplateSyncDTO source) {
        var tenant = source.getTenantId();
        if (LongUtils.notNullLong(tenant)) {
            var tenantId = baseOpenDispatcherConversion.tenant(tenant);
            AssertUtils.assertNotNull(tenantId, new ValueError("OpenTemplateSyncDTO租户不存在:" + tenant), source);
            source.setTenantId(tenantId);
        }
    }

    private void convertUser(OpenTemplateSyncDTO source) {
        //创建人
        var createBy = source.getCreateBy();
        if (LongUtils.notNullLong(createBy)) {
            var user = baseOpenDispatcherConversion.user(createBy);
            AssertUtils.assertNotNull(user, new ValueError("OpenTemplateSyncDTO创建人不存在:" + createBy), source);
            source.setCreateBy(user);
        }
        //修改人
        var updateBy = source.getUpdateBy();
        if (LongUtils.notNullLong(updateBy)) {
            var user = baseOpenDispatcherConversion.user(updateBy);
            AssertUtils.assertNotNull(user, new ValueError("OpenTemplateSyncDTO修改人不存在:" + updateBy), source);
            source.setUpdateBy(user);
        }
        //审核人
        var agreeBy = source.getAgreeBy();
        if (LongUtils.notNullLong(agreeBy)) {
            var user = baseOpenDispatcherConversion.user(agreeBy);
            AssertUtils.assertNotNull(user, new ValueError("OpenTemplateSyncDTO审核人不存在:" + agreeBy), source);
            source.setAgreeBy(user);
        }

    }

    private void convertUp(OpenTemplateSyncDTO source) {
        var upStream = source.getUpstream();
        Optional.ofNullable(upStream).ifPresent(up -> {
            //租户
            var tenant = up.getTenantId();
            var tenantId = baseOpenDispatcherConversion.tenant(tenant);
            AssertUtils.assertNotNull(tenantId, new ValueError("OpenTemplateSyncDTO upStream 租户不存在:" + tenant), source);
            up.setTenantId(tenantId);
            //承运方
            var carrierId = up.getCarrierId();
            var carrierType = up.getCarrierType();
            if (LongUtils.notNullLong(carrierId) || CarrierTypeEnum.isMyself(carrierType) || CarrierTypeEnum.isDriver(carrierType)) {
                var supplier = baseOpenDispatcherConversion.carrier(carrierId, carrierType, up.getTenantId());
                AssertUtils.assertNotNull(supplier, new ValueError("OpenTemplateSyncDTO承运方不存在:" + carrierId + "," + carrierType + "," + up.getTenantId()), source);
                up.setCarrierId(supplier.getCarrierId());
                up.setCarrierType(supplier.getCarrierType());
                if (StringUtils.isNoneBlank(supplier.getCarrierName())) {
                    up.setCarrierName(supplier.getCarrierName());
                }
            }
        });
    }

    private void convertDown(OpenTemplateSyncDTO source) {
        var downStream = source.getDownstream();
        Optional.ofNullable(downStream).ifPresent(down -> {
            //租户
            var tenant = down.getTenantId();
            var tenantId = baseOpenDispatcherConversion.tenant(tenant);
            AssertUtils.assertNotNull(tenantId, new ValueError("OpenTemplateSyncDTO downStream 租户不存在:" + tenant), source);
            down.setTenantId(tenantId);
            //客户
            var cId = down.getCustomerId();
            if (LongUtils.notNullLong(cId)) {
                if (CustomerTypeEnum.isOnline(down.getCustomerType())) {

                    var customerTenantId = baseOpenDispatcherConversion.tenant(source.getCustomerTenantId());
                    AssertUtils.assertNotNull(customerTenantId, new ValueError("OpenTemplateSyncDTO downStream customerTenantId 租户不存在:" + source.getCustomerTenantId()), source);
                    var customer = relationService.ofTenantId(customerTenantId, tenantId);
                    AssertUtils.assertNotNull(customer, new ValueError("OpenTemplateSyncDTO downStream 客户不存在:" + cId + "," + down.getCustomerType() + "," + tenantId), down);
                    down.setCustomerId(customer.getCustomerId());
                    if (StringUtils.isNotBlank(customer.getCustomerName())) {
                        down.setCustomerName(customer.getCustomerName());
                    }
                } else {
                    var customer = baseOpenDispatcherConversion.customer(cId, down.getCustomerType(), tenantId);
                    AssertUtils.assertNotNull(customer, new ValueError("OpenTemplateSyncDTO downStream 客户不存在:" + cId + "," + down.getCustomerType() + "," + tenantId), down);
                    down.setCustomerId(customer.getCustomerId());
                    if (StringUtils.isNotBlank(customer.getCustomerName())) {
                        down.setCustomerName(customer.getCustomerName());
                    }
                }
            }
        });
    }

    private void convertArea(OpenTemplateSyncDTO source) {
        Optional.ofNullable(source.getRules()).ifPresent(rule -> {
            var divideList = rule.getDivide();
            //零担
            if (!CollectionUtils.isEmpty(divideList)) {
                divideList.forEach(data -> {
                    if (StringUtils.isNotBlank(data.getFromProvinceName()) || StringUtils.isNotBlank(data.getFromCityName()) || StringUtils.isNotBlank(data.getFromDistrictName())) {
                        var from = baseOpenDispatcherConversion.area(new AddressDTO(data.getFromProvince() != null ? String.valueOf(data.getFromProvince()) : null, data.getFromProvinceName(),
                                data.getFromCity() != null ? String.valueOf(data.getFromCity()) : null, data.getFromCityName(),
                                data.getFromDistrict() != null ? String.valueOf(data.getFromDistrict()) : null, data.getFromDistrictName(), data.getFromAddress(), null));
                        AssertUtils.assertNotNull(from, new ValueError("OpenTemplateSyncDTO 零担 起点地区不存在:" + data.getFromProvinceName() + "," + data.getFromCityName() + "," + data.getFromDistrictName()), source);
                        fromArea(data, from);
                    }
                    if (StringUtils.isNotBlank(data.getToProvinceName()) || StringUtils.isNotBlank(data.getToCityName()) || StringUtils.isNotBlank(data.getToDistrictName())) {
                        var to = baseOpenDispatcherConversion.area(new AddressDTO(data.getToProvince() != null ? String.valueOf(data.getToProvince()) : null, data.getToProvinceName(),
                                data.getToCity() != null ? String.valueOf(data.getToCity()) : null, data.getToCityName(),
                                data.getToDistrict() != null ? String.valueOf(data.getToDistrict()) : null, data.getToDistrictName(), data.getToAddress(), null));
                        AssertUtils.assertNotNull(to, new ValueError("OpenTemplateSyncDTO 零担 到达地区不存在:" + data.getToProvinceName() + "," + data.getToCityName() + "," + data.getToDistrictName()), source);
                        toArea(data, to);
                    }
                });
            }
            //整车
            var wholeList = rule.getWhole();
            if (!CollectionUtils.isEmpty(wholeList)) {
                wholeList.forEach(data -> {
                    if (StringUtils.isNotBlank(data.getFromProvinceName()) || StringUtils.isNotBlank(data.getFromCityName()) || StringUtils.isNotBlank(data.getFromDistrictName())) {
                        var from = baseOpenDispatcherConversion.area(new AddressDTO(data.getFromProvince() != null ? String.valueOf(data.getFromProvince()) : null, data.getFromProvinceName(),
                                data.getFromCity() != null ? String.valueOf(data.getFromCity()) : null, data.getFromCityName(),
                                data.getFromDistrict() != null ? String.valueOf(data.getFromDistrict()) : null, data.getFromDistrictName(), data.getFromAddress(), null));
                        AssertUtils.assertNotNull(from, new ValueError("OpenTemplateSyncDTO 整车 起点地区不存在:" + data.getFromProvinceName() + "," + data.getFromCityName() + "," + data.getFromDistrictName()), source);
                        fromArea(data, from);
                    }
                    if (StringUtils.isNotBlank(data.getToProvinceName()) || StringUtils.isNotBlank(data.getToCityName()) || StringUtils.isNotBlank(data.getToDistrictName())) {
                        var to = baseOpenDispatcherConversion.area(new AddressDTO(data.getToProvince() != null ? String.valueOf(data.getToProvince()) : null, data.getToProvinceName(),
                                data.getToCity() != null ? String.valueOf(data.getToCity()) : null, data.getToCityName(),
                                data.getToDistrict() != null ? String.valueOf(data.getToDistrict()) : null, data.getToDistrictName(), data.getToAddress(), null));
                        AssertUtils.assertNotNull(to, new ValueError("OpenTemplateSyncDTO 整车 到达地区不存在:" + data.getToProvinceName() + "," + data.getToCityName() + "," + data.getToDistrictName()), source);
                        toArea(data, to);
                    }
                });
            }
            //提货
            var pickList = rule.getPick();
            if (!CollectionUtils.isEmpty(pickList)) {
                pickList.forEach(data -> {
                    if (StringUtils.isNotBlank(data.getFromProvinceName()) || StringUtils.isNotBlank(data.getFromCityName()) || StringUtils.isNotBlank(data.getFromDistrictName())) {
                        var from = baseOpenDispatcherConversion.area(new AddressDTO(data.getFromProvince() != null ? String.valueOf(data.getFromProvince()) : null, data.getFromProvinceName(),
                                data.getFromCity() != null ? String.valueOf(data.getFromCity()) : null, data.getFromCityName(),
                                data.getFromDistrict() != null ? String.valueOf(data.getFromDistrict()) : null, data.getFromDistrictName(), data.getFromAddress(), null));
                        AssertUtils.assertNotNull(from, new ValueError("OpenTemplateSyncDTO 提货 起点地区不存在:" + data.getFromProvinceName() + "," + data.getFromCityName() + "," + data.getFromDistrictName()), source);
                        fromArea(data, from);
                    }
                });
            }
            //送货
            var deliverList = rule.getDeliver();
            if (!CollectionUtils.isEmpty(deliverList)) {
                deliverList.forEach(data -> {
                    if (StringUtils.isNotBlank(data.getToProvinceName()) || StringUtils.isNotBlank(data.getToCityName()) || StringUtils.isNotBlank(data.getToDistrictName())) {
                        var to = baseOpenDispatcherConversion.area(new AddressDTO(data.getToProvince() != null ? String.valueOf(data.getToProvince()) : null, data.getToProvinceName(),
                                data.getToCity() != null ? String.valueOf(data.getToCity()) : null, data.getToCityName(),
                                data.getToDistrict() != null ? String.valueOf(data.getToDistrict()) : null, data.getToDistrictName(), data.getToAddress(), null));
                        AssertUtils.assertNotNull(to, new ValueError("OpenTemplateSyncDTO 送货 到达地区不存在:" + data.getToProvinceName() + "," + data.getToCityName() + "," + data.getToDistrictName()), source);
                        toArea(data, to);
                    }
                });
            }
        });

    }

    private void fromArea(QuotationDetailDTO detail, Address area) {
        detail.setFromProvince(StringUtils.isNotBlank(area.getProvinceCode()) ? Long.valueOf(area.getProvinceCode()) : null);
        detail.setFromProvinceName(area.getProvinceName());
        detail.setFromCity(StringUtils.isNotBlank(area.getCityCode()) ? Long.valueOf(area.getCityCode()) : null);
        detail.setFromCityName(area.getCityName());
        detail.setFromDistrict(StringUtils.isNotBlank(area.getDistrictCode()) ? Long.valueOf(area.getDistrictCode()) : null);
        detail.setFromDistrictName(area.getDistrictName());
    }

    private void toArea(QuotationDetailDTO detail, Address area) {
        detail.setToProvince(StringUtils.isNotBlank(area.getProvinceCode()) ? Long.valueOf(area.getProvinceCode()) : null);
        detail.setToProvinceName(area.getProvinceName());
        detail.setToCity(StringUtils.isNotBlank(area.getCityCode()) ? Long.valueOf(area.getCityCode()) : null);
        detail.setToCityName(area.getCityName());
        detail.setToDistrict(StringUtils.isNotBlank(area.getDistrictCode()) ? Long.valueOf(area.getDistrictCode()) : null);
        detail.setToDistrictName(area.getDistrictName());
    }

}
